package com.ruoyi.common.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        String result = converResponse(response);
        traceResponse(response, result);

        JSONObject rst = JSON.parseObject(result);
        if (200 != rst.getIntValue("code")) {
            throw new BusinessException(rst.getString("message"), RspEnmu.SYSTEM_BUSY);
        }

        return response;
    }

    private String converResponse(ClientHttpResponse response) throws IOException {
        StringBuilder inputStringBuilder = new StringBuilder();
        try (BufferedReader bufferedReader =
                     new BufferedReader(new InputStreamReader(response.getBody(), StandardCharsets.UTF_8))) {
            String line = bufferedReader.readLine();
            while (line != null) {
                inputStringBuilder.append(line);
                inputStringBuilder.append('\n');
                line = bufferedReader.readLine();
            }
        }
        return String.valueOf(inputStringBuilder);
    }

    private void traceRequest(HttpRequest request, byte[] body) {
        String traceId = IdUtils.fastSimpleUUID();
        request.getHeaders().set("TraceId", traceId);

        Map<String, String> map = new HashMap<>(16);
        map.put("requestUri", request.getURI().getPath());
        map.put("headers", String.valueOf(request.getHeaders()));
        map.put("parameter", new String(body, StandardCharsets.UTF_8));
        log.info(">>> REQUEST: {}", map);
    }

    private void traceResponse(ClientHttpResponse response, String result) throws IOException {

        Map<String, Object> map = new HashMap<>(16);
        map.put("httpCode", response.getStatusCode().value());
        map.put("responseBody", result);
        log.info(">>> RESPONSE: {}", map);
    }

}


